const {
  Model,
  DataTypes,
  // NOW,
  // UUIDV4,
} = require('sequelize');

module.exports = sequelize => {
  class Crud extends Model {
    static associate(models) {
      // define association here
      // console.log(models);
    }

    /**
     * 实例方法
     * @description 创建实例: `const jane = User.build({ name: "Jane" }); `
     * @description 创建实例: 不应new直接使用運算符來創建實例。相反，應使用build方法
     * @notice 保存实例: 实例无法与数据库通信(甚至不是异步); 调用其save才能真正保存在db `await jane.save();` -- 僅更新真正更改的字段(内部优化)
     * @notice 保存时部分更新: 仅: `jane.name = "Jane II"; jane.favoriteColor = "blue"; await jane.save({ fields: ['name'] }); `仅保存列名數組中存在的字段(部分更新)
     * @notice 创建&保存: create是將上面的build和save方法組合為一個方法的方法 - `const user = await User.create({ username: 'alice123', isAdmin: true}, { fields: ['username'] });`见"保存时部分更新"
     * @notice 实例序列化: 实例调用`.toJSON()`方法得到数据对象, 或者被`JSON.stringify(jane, null, 4)`正確編輯缩进格式
     * @notice 更新实例: `jane.name = "Ada"; await jane.save();`
     * @notice 删除实例: `await jane.destroy();`从库中删除
     * @notice 重新加載实例: `jane.name = "Ada"; await jane.reload();`被更改后可以复原
     * @notice 递增和递減整数值: increment和decrement實例方法 - 单个`const incrementResult = await jane.increment('age', { by: 2 })` 多个`await jane.increment({'age': 2,'cash': 100}` 数值相同`await jane.increment(['age', 'cash'], { by: 2 })`
     * @notice 提供 `get(this.getDataValue) - 仅改变实例记录,不会改变数据库的值` 和 set(this.setDataValue) 方法
     */
    getFullname() {
      console.log(this);
    }
  }
  /** 约束与验证
   * type         {DataTypes} 类型定义
   * primaryKey   {Boolean} 是否为主键
   * allowNull    {Boolean} 是否允许为null
   * defaultValue {any} 默认值
   * unique       {Boolean|'compositeIndex'} 创建唯一约束,字段值不能重复
   * autoIncrement {Boolean} 创建自动递增整数列
   * field        {String} 重写列名称(驼峰换成_)
   * comment      {String} 注释只能添加到MySQL，MariaDB，PostgreSQL和MSSQL中的列
   * references: {
      model: Bar,// 外链模型
      key: 'id',// 列名
      deferrable: Deferrable.INITIALLY_IMMEDIATE // With PostgreSQL
    } 创建外键其他模型
   */
  Crud.init(
    {
      id: {
        // 可省略(默认id为主键)
        type: DataTypes.INTEGER,
        primaryKey: true, // 主键
        autoIncrement: true,
        allowNull: false,
      },
      sequelize: {
        type: DataTypes.STRING(9999),
        allowNull: false,
        comment: 'sequelize模型的CRUD',
      },
      sql: {
        type: DataTypes.STRING(9999),
        comment: '等价SQL语句',
      },
      comment: {
        type: DataTypes.STRING,
        comment: '注解',
      },
      belong: {
        type: DataTypes.STRING,
        comment: '属于什么类型',
      },
      params: {
        type: DataTypes.STRING,
        comment: '参数',
      },
      mark: {
        type: DataTypes.STRING,
        comment: '补充',
      },
    },
    {
      sequelize,
      modelName: 'Crud', // 模型名称
      // freezeTableName: true // 強製表名稱等於模型名稱,不复数化(可局部或全局定义) - 通过inflection库实现
      underscored: true,
      timestamps: true, // 自動添加領域createdAt和updatedAt每一個模型
      // createdAt: false,// @type {Boolean|String}
      // updatedAt: 'updateTimestamp',// 重命名字段
      // deletedAt: 'destroyTime',

      // 软删除: 特殊列deletedAt的值將設置為該刪除請求的時間戳; 且需要時間戳才能起作用
      // `await post.destroy(); 软删除` restore恢复软删除 `await post.destroy({ force: true }); 硬删除`
      paranoid: true,
      // 由Sequelize執行的每個查詢將自動忽略軟刪除的記錄（當然，原始查詢除外）; `paranoid: false`让Sequelize不忽略

      hooks: {
        // https://sequelize.org/master/manual/hooks.html
      },

      // 范围: https://sequelize.org/master/manual/scopes.html

      // 在上面的属性中使用`unique：true`与在模型的选项中创建索引完全相同:
      // indexes: [{ unique: true, fields: ['someUnique'] }]
    },
  );

  return Crud;
};
